<?php
/**
 *+------------------
 * Lflow
 *+------------------
 * Copyright (c) 2023~2030 gitee.com/liu_guan_qing All rights reserved.本版权不可删除，侵权必究
 *+------------------
 * Author: Mr.April(405784684@qq.com)
 *+------------------
 */
declare (strict_types=1);

namespace lflow\handlers\impl;

use lflow\cfg\Configuration;
use lflow\ckpt\TaskCkpt;
use lflow\core\Execution;
use lflow\exceptions\WorkFlowException;
use lflow\impl\LogInterceptor;
use lflow\impl\SchedulerInterceptor;
use lflow\handlers\IHandler;
use lflow\lib\interface\WorkFlowInterceptor;
use lflow\lib\util\ClassUtil;
use lflow\lib\util\Logger;
use lflow\lib\util\ProxyHelper;
use ReflectionClass;

/**
 * 任务创建操作处理器
 *
 * @author Mr.April
 * @since  1.0
 */
class CreateTaskHandler implements IHandler
{

    /**
     * @var \lflow\ckpt\TaskCkpt 任务模型
     */
    private TaskCkpt $ckpt;

    /**
     * 拦截列表类
     *
     * @var array|string[]
     */
    private array $interceptList = [LogInterceptor::class];

    /**
     * 调用者需要提供用户模型
     *
     * @param \lflow\ckpt\TaskCkpt $ckpt
     */
    public function __construct(TaskCkpt $ckpt)
    {
        $this->ckpt = $ckpt;
        //装载服务
        foreach ($this->interceptList as $interceptor) {
            app()->make($interceptor);
        }
    }

    /**
     * 根据任务模型、执行对象，创建下一个任务，并添加到execution对象的tasks集合中
     */
    public function handle(Execution $execution): void
    {
        //创建任务task步骤
        $tasks = $execution->getEngine()->task()->createTask($this->ckpt, $execution);
        foreach ($tasks as $value){
            Logger::error('创建TASK'.json_encode($value->toArray()));
        }
        $execution->addTasks($tasks);
        try {
            //查找任务拦截器列表，依次对task集合进行拦截处理
            $interceptor = ClassUtil::instantiateClass(Configuration::class)->interceptList(WorkFlowInterceptor::class);
            foreach ($interceptor as $interceptors) {
                $interceptors->intercept($execution);
            }
        } catch (\Exception $e) {
            Logger::error("拦截器执行失败=" . $e->getMessage());
            throw new WorkFlowException($e);
        }
    }
}
